package cn.com.surker.task;

import cn.com.surker.base.system.dao.SysLineDao;
import cn.com.surker.base.system.entity.SysControlStorage;
import cn.com.surker.base.system.entity.SysLine;
import cn.com.surker.database.JDBCTemplateCache;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.lab.entity.MaterialRate;
import cn.com.surker.system.service.SysLineService;
import cn.com.surker.util.MathUtils;
import cn.com.surker.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 丰都现场站的数据同步
 *
 * @author luotao
 * @date 2025/4/2
 */
@Slf4j
@Configuration
@EnableScheduling
public class FengDuTask {

	@Value("${erp.org.code}")
	private String orgCode;

	@Autowired
	private SysLineService sysLineService;

	/**
	 * erp的数据源
	 */
	// @Qualifier("mysqlJdbcTemplate")
	@Autowired
	private JdbcTemplate mysqlJdbcTemplate;


	/**
	 * 2分钟同步一次
	 */
	// @Scheduled(cron = "0 0/1 * * * ?")
	public void sysMaterialLab() {
		//	判定是否丰都站
		if (!orgCode.equals("FD")) {
			return;
		}
		//  查询erp材料配比数据
		String queryErpSql = "select a.line_id,a.strength_id,a.storage_id,a.value,b.strength strengthName,a.status from lab_level_material_old a" +
			"\tLEFT JOIN base_strength b ON a.strength_id = b.id";
		List<MaterialRate> rateList = mysqlJdbcTemplate.query(queryErpSql, BeanPropertyRowMapper.newInstance(MaterialRate.class));
		if (rateList == null || rateList.isEmpty()) {
			return;
		}
		//	根据生产线分钟
		Map<Long, List<MaterialRate>> lineRateMap = rateList.stream().collect(Collectors.groupingBy(MaterialRate::getLineId));
		//	查询工控数据
		String queryWcSql = "select id,line_id,strength_name,storage_id,value from control_storage_value where line_id = ?";
		//	插入工控数据
		String insertWcSql = "insert into control_storage_value (line_id,strength_name,storage_id,value) values (?,?,?,?)";
		//	更新数据
		String updateWcSql = "update control_storage_value set value = ? where id = ?";
		//	删除数据
		String delWcSqlById = "delete from control_storage_value where id = ?";
		//	查询工控数据
		List<SysLine> lineList = sysLineService.findAll();
		for (SysLine sysLine : lineList) {
			Long lineId = sysLine.getId();
			//	取出生产线下的配比数据
			List<MaterialRate> lineRateList = lineRateMap.get(lineId);
			if (lineRateList == null || lineRateList.isEmpty()) {
				//	该线无数据
				continue;
			}
			JdbcTemplate lineJdbcTemplate = JDBCTemplateCache.getLineJdbcTemplate(sysLine);
			//	查询是否应删除数据
			MaterialRate mr = lineRateList.get(0);
			if (StateEnum.DISABLED.getCode().equals(mr.getStatus())) {
				//	删除全部数据
				String delWcSql = "delete from control_storage_value";
				lineJdbcTemplate.update(delWcSql);
				continue;
			}
			//	工控线号
			Long controlLineId = sysLine.getControlLineId();
			//	转换成8位长度的id
			String wcLineId = StringUtils.toFixedLengthString(controlLineId, 8);
			//	查询工控数据
			Object[] wcParam = {wcLineId};
			List<Map<String, Object>> wcList = lineJdbcTemplate.queryForList(queryWcSql, wcParam);
			if (wcList == null || wcList.isEmpty()) {
				//	没有数据,需要新增
				List<Object[]> params = new ArrayList<>();
				for (int i = 0, s = lineRateList.size(); i < s; i++) {
					MaterialRate materialRate = lineRateList.get(i);
					String strengthName = materialRate.getStrengthName();
					Long storageId = materialRate.getStorageId();
					Double value = materialRate.getValue();
					Object[] param = {wcLineId, strengthName, storageId, value};
					params.add(param);
				}
				// 插入数据
				lineJdbcTemplate.batchUpdate(insertWcSql, params);
				continue;
			}
			// 将wcList转换为Map，键为(strengthName, storageId)
			Map<String, Map<String, Object>> wcMap = wcList.stream()
				.collect(Collectors.toMap(
					map -> {
						String strengthName = (String) map.get("strength_name");
						Long storageId = ((Number) map.get("storage_id")).longValue();
						//	拼接key
						String key = strengthName + "_" + storageId;
						return key;
					},
					Function.identity(),
					(existing, replacement) -> existing // 处理重复键，保留现有值（根据业务需求调整）
				));
			//	工控存在数据,查看erp的数据工控是否存在
			List<Object[]> addParams = new ArrayList<>();
			for (MaterialRate materialRate : lineRateList) {
				//	强度等级
				String strengthName = materialRate.getStrengthName();
				//	仓位id
				Long storageId = materialRate.getStorageId();
				//	操作值
				Double value = materialRate.getValue();
				//	拼接key
				String key = strengthName + "_" + storageId;
				//	取出工控数据
				Map<String, Object> wcEntry = wcMap.get(key);
				if (wcEntry != null) {
					// 存在匹配项，检查值是否需要更新
					Object wcValue = wcEntry.get("value");
					BigDecimal a = BigDecimal.valueOf(value);
					BigDecimal b = (BigDecimal) wcValue;
					int compare = a.compareTo(b);
					if (compare != 0) {
						//	值不相同,要更新
						Object wcId = wcEntry.get("id");
						Object[] updateParam = {value, wcId};
						lineJdbcTemplate.update(updateWcSql, updateParam);
					}
					wcMap.remove(key); // 移除已处理的条目
				} else {
					// 不存在匹配项，准备新增
					addParams.add(new Object[]{wcLineId, strengthName, storageId, value});
				}
			}
			//	进入此处依然存在的数据,表示工控机上存在,erp中没有,应当进行删除操作
			if (!wcMap.isEmpty()) {
				wcMap.forEach((key, item) -> {
					Object id = item.get("id");
					Object[] delParam = {id};
					lineJdbcTemplate.update(delWcSqlById, delParam);
				});
			}
			if (addParams.size() > 0) {
				//	工控新增数据
				lineJdbcTemplate.batchUpdate(insertWcSql, addParams);
			}
		}
	}

}
